import { describe, expect, it } from 'vitest';
import gql from 'graphql-tag';
import { queryAsAdmin } from '../../utils/testQuery';

const LIST_QUERY = gql`
  query malwareAnalyses(
    $first: Int
    $after: ID
    $orderBy: MalwareAnalysesOrdering
    $orderMode: OrderingMode
    $filters: FilterGroup
    $search: String
  ) {
    malwareAnalyses(
      first: $first
      after: $after
      orderBy: $orderBy
      orderMode: $orderMode
      filters: $filters
      search: $search
    ) {
      edges {
        node {
          id
          result_name
          product
        }
      }
    }
  }
`;

const READ_QUERY = gql`
  query malwareAnalysis($id: String!) {
    malwareAnalysis(id: $id) {
      id
      standard_id
      result_name
      product
      toStix
    }
  }
`;

describe('MalwareAnalysis resolver standard behavior', () => {
  let malwareAnalysisInternalId;
  const malwareAnalysisStixId = 'malware-analysis--49564d77-8591-5751-a454-ce7ea2291693';
  it('should malwareAnalysis created', async () => {
    const CREATE_QUERY = gql`
      mutation MalwareAnalysisAdd($input: MalwareAnalysisAddInput!) {
        malwareAnalysisAdd(input: $input) {
          id
          result_name
          product
        }
      }
    `;
    // Create the malwareAnalysis
    const MALWAREANALYSIS_TO_CREATE = {
      input: {
        result_name: 'Malware-Analysis',
        stix_id: malwareAnalysisStixId,
        product: 'Malware-Analysis product',
      },
    };
    const queryResult = await queryAsAdmin({
      query: CREATE_QUERY,
      variables: MALWAREANALYSIS_TO_CREATE,
    });
    expect(queryResult).not.toBeNull();
    expect(queryResult.data.malwareAnalysisAdd).not.toBeNull();
    expect(queryResult.data.malwareAnalysisAdd.result_name).toEqual('Malware-Analysis');
    malwareAnalysisInternalId = queryResult.data.malwareAnalysisAdd.id;
  });
  it('should malwareAnalysis loaded by internal id', async () => {
    const queryResult = await queryAsAdmin({ query: READ_QUERY, variables: { id: malwareAnalysisInternalId } });
    expect(queryResult).not.toBeNull();
    expect(queryResult.data.malwareAnalysis).not.toBeNull();
    expect(queryResult.data.malwareAnalysis.id).toEqual(malwareAnalysisInternalId);
    expect(queryResult.data.malwareAnalysis.toStix.length).toBeGreaterThan(5);
  });
  it('should malwareAnalysis loaded by stix id', async () => {
    const queryResult = await queryAsAdmin({ query: READ_QUERY, variables: { id: malwareAnalysisStixId } });
    expect(queryResult).not.toBeNull();
    expect(queryResult.data.malwareAnalysis).not.toBeNull();
    expect(queryResult.data.malwareAnalysis.id).toEqual(malwareAnalysisInternalId);
  });
  it('should list malwareAnalyses', async () => {
    const queryResult = await queryAsAdmin({ query: LIST_QUERY, variables: { first: 10 } });
    expect(queryResult.data.malwareAnalyses.edges.length).toEqual(2);
  });
  it('should update malwareAnalysis', async () => {
    const UPDATE_QUERY = gql`
        mutation MalwareAnalysisEdit($id: ID!, $input: [EditInput]!) {
            malwareAnalysisFieldPatch(id: $id, input: $input) {
                id
                result_name
            }
        }
    `;
    const queryResult = await queryAsAdmin({
      query: UPDATE_QUERY,
      variables: { id: malwareAnalysisInternalId, input: { key: 'result_name', value: ['Malware-Analysis - test'] } },
    });
    expect(queryResult.data.malwareAnalysisFieldPatch.result_name).toEqual('Malware-Analysis - test');
  });
  it('should context patch malwareAnalysis', async () => {
    const CONTEXT_PATCH_QUERY = gql`
        mutation MalwareAnalysisEdit($id: ID!, $input: EditContext!) {
            malwareAnalysisContextPatch(id: $id,  input: $input) {
                id
            }
        }
    `;
    const queryResult = await queryAsAdmin({
      query: CONTEXT_PATCH_QUERY,
      variables: { id: malwareAnalysisInternalId, input: { focusOn: 'product' } },
    });
    expect(queryResult.data.malwareAnalysisContextPatch.id).toEqual(malwareAnalysisInternalId);
  });
  it('should context clean malwareAnalysis', async () => {
    const CONTEXT_CLEAN_QUERY = gql`
        mutation MalwareAnalysisEdit($id: ID!) {
            malwareAnalysisContextClean(id: $id) {
                id
            }
        }
    `;
    const queryResult = await queryAsAdmin({
      query: CONTEXT_CLEAN_QUERY,
      variables: { id: malwareAnalysisInternalId },
    });
    expect(queryResult.data.malwareAnalysisContextClean.id).toEqual(malwareAnalysisInternalId);
  });
  it('should add relation in malwareAnalysis', async () => {
    const RELATION_ADD_QUERY = gql`
          mutation MalwareAnalysisEdit($id: ID!, $input: StixRefRelationshipAddInput!) {
              malwareAnalysisRelationAdd(id: $id, input: $input) {
                  id
                  from {
                      ... on MalwareAnalysis {
                          objectMarking {
                              id
                          }
                      }
                  }
              }
          }
      `;
    const queryResult = await queryAsAdmin({
      query: RELATION_ADD_QUERY,
      variables: {
        id: malwareAnalysisInternalId,
        input: {
          toId: 'marking-definition--78ca4366-f5b8-4764-83f7-34ce38198e27',
          relationship_type: 'object-marking',
        },
      },
    });
    expect(queryResult.data.malwareAnalysisRelationAdd.from.objectMarking.length).toEqual(1);
  });
  it('should delete relation in malwareAnalysis', async () => {
    const RELATION_DELETE_QUERY = gql`
            mutation MalwareAnalysisEdit($id: ID!, $toId: StixRef!, $relationship_type: String!) {
                malwareAnalysisRelationDelete(id: $id, toId: $toId, relationship_type: $relationship_type) {
                    id
                    objectMarking {
                        id
                    }
                }
            }
        `;
    const queryResult = await queryAsAdmin({
      query: RELATION_DELETE_QUERY,
      variables: {
        id: malwareAnalysisInternalId,
        toId: 'marking-definition--78ca4366-f5b8-4764-83f7-34ce38198e27',
        relationship_type: 'object-marking',
      },
    });
    expect(queryResult.data.malwareAnalysisRelationDelete.objectMarking.length).toEqual(0);
  });
  it('should malwareAnalysis deleted', async () => {
    const DELETE_QUERY = gql`
            mutation malwareAnalysisDelete($id: ID!) {
                malwareAnalysisDelete(id: $id)
            }
        `;
    // Delete the malwareAnalysis
    await queryAsAdmin({
      query: DELETE_QUERY,
      variables: { id: malwareAnalysisInternalId },
    });
    // Verify is no longer found
    const queryResult = await queryAsAdmin({ query: READ_QUERY, variables: { id: malwareAnalysisStixId } });
    expect(queryResult).not.toBeNull();
    expect(queryResult.data.malwareAnalysis).toBeNull();
  });
});
